using Unity.Collections;
using Unity.Entities;
using UnityEngine;

namespace DOTS.DOD.LESSON9
{
    public enum BuildingType //建筑类型
    {
        BT_Spawner, //兵营
        BT_DefenderTower, //防御塔
        BT_MAX
    }

    public enum ArmorType //护甲类型
    {
        AT_None = 0, //无甲
        AT_Light, //轻甲
        AT_Normal, //中甲
        AT_Heavy, //重甲
        AT_Hero, //特殊类型甲
        AT_Max
    }

    public enum DamageType //伤害类型
    {
        DT_Slash = 0, //挥砍伤害
        DT_Pricks, //穿刺伤害
        DT_Smash, //粉碎伤害
        DT_Magic, //魔法伤害
        DT_Chaos, //混合型伤害
        DT_Hero, //特殊类伤害
        DT_Max
    }

    /// <summary>
    /// 所有的Component（不使用BlobAsset）
    /// </summary>
    struct EntitySpawnerAllComponentData : IComponentData
    {
        public Entity EntityProtoType; //生成entity原型对象，用于实例化克隆                8 byte
        public BuildingType EBuilding; //建筑类型                                       4 byte
        public int Level; //当前等级                                                    4 byte
        public float TickTime; //间隔多少秒生成一次                                      4 byte
        public int SpawnCountPerTickTime; //每次生成的个数                               4 byte
        public float MaxLife; //最大生命值                                              4 byte
        public float CurLife; //当前生命值                                              4 byte
        public ArmorType EArmor; //护甲类型                                             4 byte
        public DamageType EDamage; //伤害类型                                           4 byte
        public float MaxDamage; //最大伤害                                              4 byte
        public float MinDamage; //最小伤害                                              4 byte
        public float UpgradeTime; //升级时间                                            4 byte
        public float UpgradeCost; //升级费用                                            4 byte
    }

    /// <summary>
    /// Spawner的组件数据 动态、独有（使用BlobAsset）
    /// </summary>
    struct EntitySpawnerComponentData : IComponentData
    {
        public float CurLife; //当前生命值                                              4 byte
    }

    /// <summary>
    /// Spawner的组件数据 只读、共用（使用BlobAsset）
    /// </summary>
    struct EntitySpawnerBlobData
    {
        public Entity EntityProtoType; //生成entity原型对象，用于实例化克隆                8 byte
        public BuildingType EBuilding; //建筑类型                                       4 byte
        public int Level; //当前等级                                                    4 byte
        public float TickTime; //间隔多少秒生成一次                                      4 byte
        public int SpawnCountPerTickTime; //每次生成的个数                               4 byte
        public float MaxLife; //最大生命值                                              4 byte
        public ArmorType EArmor; //护甲类型                                             4 byte
        public DamageType EDamage; //伤害类型                                           4 byte
        public float MaxDamage; //最大伤害                                              4 byte
        public float MinDamage; //最小伤害                                              4 byte
        public float UpgradeTime; //升级时间                                            4 byte
        public float UpgradeCost; //升级费用                                            4 byte
    }

    struct EntitySpawnerSettings : IComponentData
    {
        public BlobAssetReference<EntitySpawnerBlobData> BlobSettings; //8 byte
    }

    public class EntitySpawnerAuthoring : MonoBehaviour
    {
        public GameObject EntityArchetype;
        public BuildingType EBuilding;
        public int Level;
        public float TickTime;
        public int SpawnCountPerTickTime;
        public float MaxLife;
        public float CurLife;
        public ArmorType EArmor;
        public DamageType EDamage;
        public float MaxDamage;
        public float MinDamage;
        public float UpgradeTime;
        public float UpgradeCost;

        class Baker : Baker<EntitySpawnerAuthoring>
        {
            public override void Bake(EntitySpawnerAuthoring authoring)
            {
                var entity = GetEntity(TransformUsageFlags.None);
                //使用AllComponentData
                // AddComponent(new EntitySpawnerAllComponentData()
                // {
                //     EntityProtoType = GetEntity(authoring.EntityArchetype),
                //     EBuilding = authoring.EBuilding,
                //     Level = authoring.Level,
                //     TickTime = authoring.TickTime,
                //     SpawnCountPerTickTime = authoring.SpawnCountPerTickTime,
                //     MaxLife = authoring.MaxLife,
                //     CurLife = authoring.CurLife,
                //     EArmor = authoring.EArmor,
                //     EDamage = authoring.EDamage,
                //     MaxDamage = authoring.MaxDamage,
                //     MinDamage = authoring.MinDamage,
                //     UpgradeTime = authoring.UpgradeTime,
                //     UpgradeCost = authoring.UpgradeCost,
                // });

                //使用BlobAsset
                AddComponent(entity, new EntitySpawnerComponentData()
                {
                    CurLife = authoring.CurLife,
                });
                var setting = CreateSpawnerBlobSettings(authoring);
                AddBlobAsset(ref setting, out var hash);
                AddComponent(entity, new EntitySpawnerSettings()
                {
                    BlobSettings = setting,
                });
            }

            BlobAssetReference<EntitySpawnerBlobData> CreateSpawnerBlobSettings(EntitySpawnerAuthoring authoring)
            {
                var builder = new BlobBuilder(Allocator.Temp);
                ref EntitySpawnerBlobData spawnerBlobData = ref builder.ConstructRoot<EntitySpawnerBlobData>();

                spawnerBlobData.EntityProtoType = GetEntity(authoring.EntityArchetype, TransformUsageFlags.Dynamic);
                spawnerBlobData.EBuilding = authoring.EBuilding;
                spawnerBlobData.Level = authoring.Level;
                spawnerBlobData.TickTime = authoring.TickTime;
                spawnerBlobData.SpawnCountPerTickTime = authoring.SpawnCountPerTickTime;
                spawnerBlobData.MaxLife = authoring.MaxLife;
                spawnerBlobData.EArmor = authoring.EArmor;
                spawnerBlobData.EDamage = authoring.EDamage;
                spawnerBlobData.MaxDamage = authoring.MaxDamage;
                spawnerBlobData.MinDamage = authoring.MinDamage;
                spawnerBlobData.UpgradeTime = authoring.UpgradeTime;
                spawnerBlobData.UpgradeCost = authoring.UpgradeCost;

                var result = builder.CreateBlobAssetReference<EntitySpawnerBlobData>(Allocator.Persistent);
                builder.Dispose();
                return result;
            }
        }
    }
}